package moe.loliserver.utils;

import moe.loliserver.LoliServerStart;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import javax.annotation.Nullable;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.LinkedHashMap;
import java.util.Map;

public class LoliServerConfigUtil {

    private static File loliconfig = new File("loliserver.yml");
    private static Yaml yaml = null;
    private static LinkedHashMap<String, Object> configMap = null;
    static {
        load();
    }

    public static void load() {
        try {
            copyLoliConfig();
            DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
            yaml = new Yaml(options);
            configMap = yaml.load(new InputStreamReader(new FileInputStream(loliconfig), StandardCharsets.UTF_8));
        } catch (Throwable ignored) {
            throw new RuntimeException("Faild to load: " + loliconfig.getName());
        }
    }

    @Nullable
    private static Object getOrPut(String key, Object defaultReturn, Map<String, Object> map) {
        Object mapResult = map.get(key);
        if (mapResult == null) {
            if (defaultReturn == null) {
                return null;
            }

            map.put(key, defaultReturn);
            try {
                yaml.dump(configMap, new OutputStreamWriter(new FileOutputStream(loliconfig), StandardCharsets.UTF_8));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            return defaultReturn;
        }
        return mapResult;
    }

    private static Object oLoli(String key, Object defaultReturn) {
        String[] keySet = key.split("\\.");
        int length = keySet.length;
        Map<String, Object> curMap = configMap;
        for (int i = 0; i < length; i++) {
            if (i + 1 == length) {
                return getOrPut(keySet[i], defaultReturn, curMap);
            }
            Object curResult = getOrPut(keySet[i], new LinkedHashMap<String, Object>(), curMap);
            if (curResult instanceof Map) {
                curMap = (Map<String, Object>) curResult;
            }
        }
        return defaultReturn;
    }

    public static String sLoli(String key, String defaultReturn) {
        Object oLili = oLoli(key, defaultReturn);
        if (oLili instanceof String) {
            return (String) oLili;
        } else {
            return defaultReturn;
        }
    }

    public static Boolean bLoli(String key, boolean defaultReturn) {
        Object oLili = oLoli(key, defaultReturn);
        if (oLili instanceof Boolean) {
            return (Boolean) oLili;
        } else {
            return defaultReturn;
        }
    }

    private static void copyLoliConfig() {
        try {
            if (!loliconfig.exists()) {
                loliconfig.mkdirs();
                Files.copy(LoliServerStart.class.getClassLoader().getResourceAsStream("configs/loliserver.yml"), loliconfig.toPath(), StandardCopyOption.REPLACE_EXISTING);
            }
        } catch (Exception e) {
            System.out.println("File copy exception!");
        }
    }
}

